import { Injectable } from '@angular/core';
import { Graph, registerNode } from '@antv/g6';
import { GraphOptions, ITEM_TYPE, ModelConfig } from '@antv/g6/lib/types';

@Injectable({
  providedIn: 'root'
})
export class GraphService {

  constructor() {
    this.registerNode();
  }
  /**
   * 生成图表
   * @param container 容器
   */
  generateGraph(container: HTMLElement, cfg?: GraphOptions) {
    const width = container.offsetWidth;
    const height = container.offsetHeight;
    const config: GraphOptions = {
      container,
      width,
      height,
      layout: {
        type: 'dagre',
        nodesep: 50, // 节点之间的间距
        ranksep: 10, // 层间距
        controlPoints: true
      },
      defaultNode: { // 节点的类型，这里使用注册的节点 custom
        type: 'custom',
      },
      defaultEdge: { // 边（节点连线）的样式
        type: 'quadratic',
        style: {
          radius: 10,
          offset: 15,
          lineWidth: 2,
          endArrow: true,
          stroke: '#C2C8D5'
        },
      },
      nodeStateStyles: { // 节点选中样式
        selected: {
          stroke: '#d9d9d9',
          fill: '#1890ff',
        },
        finished: {
          stroke: '#d9d9d9',
          fill: '#00ff00'
        }
      },
      modes: {
        default: [
          'zoom-canvas', // canvas可缩放
          'drag-canvas'
        ],
      },
      fitView: true,
      fitCenter: true,
      maxZoom: 1
    };
    const graph = new Graph({ ...config, ...cfg });
    return graph;
  }

  /**
   * 注册自定义节点
   */
  registerNode() {
    registerNode(
      'custom',
      {
        drawShape(cfg, group) {
          const rect = group.addShape('rect', {
            attrs: {
              x: -50,
              y: -15,
              width: 100,
              height: 30,
              radius: 5,
              stroke: '#5B8FF9',
              fill: '#ffffff',
              lineWidth: 1,
            },
            name: 'rect-shape',
          });
          return rect;
        }
      },
      'single-node',
    );
  }
  /**
   *
   * @param graph graph
   * @param type 元素类型(node | edge | group)
   * @param model 元素数据模型
   * @param stack  本次操作是否入栈，默认为 true
   * @returns Item 元素实例
   *
   */
  protected addItem(graph: Graph, type: ITEM_TYPE, model: ModelConfig, stack: boolean = true) {
    return graph.addItem(type, model, stack);
  }
}
